﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FitnessMVC.Data
{
    public class SqlFitnessRepository : IFitnessRepository
    {
        private FitnessDataContext _data = new FitnessDataContext();

        #region IFitnessRepository Members

        public User GetUserByEmail(string email)
        {
            var u = from m in _data.Memberships
                    where m.Email == email
                    select m.User;

            int c = u.Count();
            if (c < 1)
                return null;

            return u.First();
        }

        public User GetUserByUserId(Guid userID)
        {
            return _data.Users.First(x => x.UserId == userID);
        }

        public User GetUserByName(string name)
        {
            var result = from u in _data.Users
                         where u.UserName == name
                         select u;

            return result.FirstOrDefault();
        }

        public void DeleteUser(User u)
        {
            // TODO, figure out best way to handle deleting a user.
            throw new NotImplementedException();
        }

        public void DeleteUser(Guid userID)
        {
            // TODO, figure out best way to handle deleting a user.
            throw new NotImplementedException();
        }

        public UserProfile GetUserProfile(Guid userID)
        {
            return (from p in _data.UserProfiles
                    where p.UserID == userID
                    select p).FirstOrDefault();
        }

        public UserProfile GetUserProfile(int profileID)
        {
            return _data.UserProfiles.FirstOrDefault(x => x.ProfileID == profileID);
        }

        public UserProfile GetUserProfile(string userName)
        {
            var user = (from u in _data.Users
                    where u.UserName == userName
                    select u).FirstOrDefault();

            if ( user == null )
                return null;

            return _data.UserProfiles.FirstOrDefault(x => x.UserID == user.UserId);
        }

        public void UpdateUserProfile(UserProfile up)
        {
            UserProfile toUpdate = _data.UserProfiles.First(x => x.ProfileID == up.ProfileID);
            if (toUpdate == null)
                throw new InvalidOperationException(
                    "Passed in Userprofile was not found, cannot update it, check for valid ProfileID");

            toUpdate.AboutMe = up.AboutMe;
            toUpdate.BirthDate = up.BirthDate;
            toUpdate.FirstName = up.FirstName;
            toUpdate.LastName = up.LastName;
            toUpdate.Hometown = up.Hometown;
            toUpdate.MemberSince = up.MemberSince;
            toUpdate.ProfilePicID = up.ProfilePicID;
            toUpdate.Sex = up.Sex;
            toUpdate.UserID = up.UserID;

            // Not sure if I need to do a submit changes.
        }

        public void DeleteUserProfile(UserProfile up)
        {
            _data.UserProfiles.DeleteOnSubmit(up);
        }

        public void AddUserProfile(UserProfile up)
        {
            _data.UserProfiles.InsertOnSubmit(up);
        }

        public IQueryable<UserProfile> GetAllProfiles()
        {
            return from u in _data.UserProfiles
                   select u;
        }

        public IQueryable<UserProfile> FindUserProfileByName(string name)
        {
            string n = name.ToLower();
            return from x in _data.UserProfiles
                   where x.FirstName.ToLower().Contains(n) ||
                         x.LastName.ToLower().Contains(n)
                   select x;                    
        }

        public IQueryable<UserProfile> FindSimilarProfiles(UserProfile up)
        {
            return from x in _data.UserProfiles
                   where x.Hometown.Equals(up.Hometown, StringComparison.InvariantCultureIgnoreCase)
                   || x.BirthDate.Month == up.BirthDate.Month
                   select x;
        }

        public UserPicture GetUserPicture(int picID)
        {
            return _data.UserPictures.FirstOrDefault(x => x.PictureId == picID);
        }

        public void UpdateUserPicture(UserPicture pic)
        {
            UserPicture toUpdate = _data.UserPictures.FirstOrDefault(x => x.PictureId == pic.PictureId);
            if (toUpdate == null)
                throw new InvalidOperationException(
                    "Passed in UserPicture was not found, cannot update it, check for valid PictureID");

            toUpdate.PicturePath = pic.PicturePath;
            toUpdate.UserId = pic.UserId;
        }

        public void DeleteUserPicture(UserPicture pic)
        {
            _data.UserPictures.DeleteOnSubmit(pic);
        }

        public void DeleteUserPicturesByUserId(Guid userId)
        {
            var pics = from p in _data.UserPictures
                       where p.UserId == userId
                       select p;

            _data.UserPictures.DeleteAllOnSubmit(pics);
        }

        public void AddUserPicture(UserPicture pic)
        {
            _data.UserPictures.InsertOnSubmit(pic);
        }

        public IQueryable<UserPicture> FindUserPictureByUser(Guid userID)
        {
            return from p in _data.UserPictures
                   where p.UserId == userID
                   select p;
        }

        public void Save()
        {
            _data.SubmitChanges();
        }

        public IQueryable<User> GetUserBuddies(string userName)
        {
            return from buddy in _data.UserBuddies
                   let user = (from u in _data.Users
                               where u.UserName == userName
                               select u).First()
                   where buddy.User1Id == user.UserId ||
                         buddy.User2Id == user.UserId
                   select buddy.User1Id == user.UserId ? buddy.LeftUser : buddy.RightUser;
        }

        public bool AreUsersBuddies(string user1Name, string user2Name)
        {
            return GetUserBuddies(user1Name).Any(x => x.UserName == user2Name);
        }

        public IQueryable<UserPicture> GetUserPictures(string userName)
        {
            return from pics in _data.UserPictures
                   let userId = (from usr in _data.Users
                                 where usr.UserName == userName
                                 select usr.UserId).First()
                   where pics.UserId == userId
                   select pics;
        }

        public void SetUserProfilePic(string name, UserPicture pic)
        {
            var usr = GetUserProfile(name);
            usr.ProfilePicID = pic.PictureId;                        
        }

        #endregion
    }
}
